﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace DNA.Mvc.jQuery
{
    public class FilterBuilder<T>
    {
        private List<string> exprs = new List<string>();
        private string fieldName = "";

        public FilterBuilder(string name) { fieldName = name; }
        
        private string formatStr(T value)
        {
            if (value.GetType().Equals(typeof(string)))
              return "'"+value.ToString()+"'";
            return value.ToString();
        }

        public FilterBuilder<T> StartsWith(T value)
        {
            exprs.Add(fieldName + "~startswith~" + "'" + value.ToString() + "%'");
            return this;
        }

        public FilterBuilder<T> Contains(T value)
        {
            exprs.Add(fieldName + "~contains~" + "'%" + value.ToString() + "%'");
            return this;
        }

        public FilterBuilder<T> EndsWith(T value)
        {
            exprs.Add(fieldName + "~endswith~" + "'%" + value.ToString() + "'");
            return this;
        }

        public new FilterBuilder<T> Equals(T value)
        {
            exprs.Add(fieldName + "~eq~" + formatStr(value));
            return this;
        }

        public FilterBuilder<T> Lt(T value)
        {
            exprs.Add(fieldName + "~lt~" + value.ToString());
            return this;
        }
        
        public FilterBuilder<T> Le(T value)
        {
            exprs.Add(fieldName + "~le~" + value.ToString());
            return this;
        }

        public FilterBuilder<T> Ge(T value)
        {
            exprs.Add(fieldName + "~ge~" + value.ToString());
            return this;
        }

        public FilterBuilder<T> Gt(T value)
        {
            exprs.Add(fieldName + "~gt~" + value.ToString());
            return this;
        }
        
        public FilterBuilder<T> Neq(T value)
        {
            exprs.Add(fieldName + "~neq~" + formatStr(value));
            return this;
        }

        public FilterBuilder<T> Not()
        {
            exprs.Add("not");
            return this;
        }

        public FilterBuilder<T> Or()
        {
            exprs.Add("or");
            return this;
        }

        public FilterBuilder<T> And()
        {
            exprs.Add("and");
            return this;
        }

        public override string ToString()
        {
            return string.Join("~", exprs.ToArray());
        }
    }

    public class FilterBuilderFactory<TModel>
        where TModel:class
    {
        private List<object> exprs=new List<object>();

        public FilterBuilder<TValue> Add<TValue>(Expression<Func<TModel, TValue>> expression)
        {
            ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression<TModel, TValue>(expression, new ViewDataDictionary<TModel>());
            var builder= new FilterBuilder<TValue>(modelMetadata.PropertyName);
            exprs.Add(builder);
            return builder;
        }

        internal string GetResult()
        {
            string result = "";
            var strArgs = new List<string>();
            foreach (var expr in exprs)
                strArgs.Add(expr.ToString());

            result = string.Join("-", strArgs.ToArray());
            return result;
        }
    }
}
